package com.example.his.api.front.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.his.api.db.dao.CustomerDao;
import com.example.his.api.db.dao.OrderDao;
import com.example.his.api.db.pojo.CustomerEntity;
import com.example.his.api.front.service.CustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author huixh
 */
@Slf4j
@Service("FrontCustomerServiceImpl")
public class CustomerServiceImpl extends ServiceImpl<CustomerDao, CustomerEntity> implements CustomerService {

    private static final String SMS_CODE_REFRESH_KEY = "sms_code_refresh_";

    private static final String SMS_CODE_KEY = "sms_code_";

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private OrderDao orderDao;

    @Override
    public boolean sendSmsCode(String tel) {

        String code = RandomUtil.randomString(6);
        log.error("发送短信验证码成功，验证码为：{}", code);
        String smsRefreshKey = SMS_CODE_REFRESH_KEY + tel;

        if (Boolean.TRUE.equals(redisTemplate.hasKey(smsRefreshKey))) {
            return false;
        }

        redisTemplate.opsForValue().set(smsRefreshKey, code, 2, TimeUnit.MINUTES);

        redisTemplate.opsForValue().set(SMS_CODE_KEY + tel, code, 5, TimeUnit.MINUTES);

        // 短信验证 发送成功
        return true;
    }

    @Override
    public HashMap<String, Object> login(String tel, String code) {
        String codeKey = SMS_CODE_KEY + tel;
        String smsRefreshKey = SMS_CODE_REFRESH_KEY + tel;
        HashMap<String, Object> result = new HashMap<>();
        if (Boolean.TRUE.equals(redisTemplate.hasKey(codeKey)) &&
                Objects.equals(((String) Objects.requireNonNull(redisTemplate.opsForValue().get(codeKey))).toLowerCase(), code.toLowerCase())) {
            redisTemplate.delete(codeKey);
            redisTemplate.delete(smsRefreshKey);
            Integer userId = this.baseMapper.searchIdByTel(tel);
            if (userId == null) {
                CustomerEntity customerEntity = new CustomerEntity();
                customerEntity.setTel(tel);
                this.baseMapper.insert(customerEntity);
                userId = customerEntity.getId();
            }
            result.put("id", userId);
            result.put("msg", "登录成功");
            result.put("result", true);
        } else {
            // 验证码错误
            result.put("result", false);
            result.put("msg", "短信验证码错误或已过期");
        }
        return result;
    }

    @Override
    public Map<String, Object> searchSummary(Integer id) {
        Map<String, Object> result = new HashMap<>();
        CustomerEntity customerEntity = this.baseMapper.selectById(id);
        // 把对象转为 map
        if (customerEntity != null) {
            Map<String, Object> userMap = BeanUtil.beanToMap(customerEntity,"name","sex","tel","photo","createTime");
            Map<String, Object> infoMap = orderDao.searchFrontStatistics(id);
            //  合并两个map
            result.putAll(userMap);
            result.putAll(infoMap);
        }
        return result;
    }


    public boolean updateCustomer(Map<String,Object> map) {
        LambdaUpdateWrapper<CustomerEntity> updateWrapper = Wrappers.lambdaUpdate(CustomerEntity.class)
                .set(MapUtil.getStr(map, "name") != null, CustomerEntity::getName, MapUtil.getStr(map, "name"))
                .set(MapUtil.getStr(map, "sex") != null, CustomerEntity::getSex, MapUtil.getStr(map, "sex"))
                .set(MapUtil.getStr(map, "photo") != null, CustomerEntity::getPhoto, MapUtil.getStr(map, "photo"))
                .set(MapUtil.getStr(map, "tel") != null, CustomerEntity::getTel, MapUtil.getStr(map, "tel"))
                .eq(CustomerEntity::getId, MapUtil.getInt(map, "id"));
        return update(updateWrapper);
    }

}
